<?php

require 'libs/router/Router.php';
require 'libs/router/Route.php';

require 'config/urls.php';

require 'libs/database/idiorm.php';
require 'libs/database/paris.php';

/**
 * Inspects the given request and 
 */
class ControllerLoader {
    private $router;
    
    function     __construct() {        
        $this->router = new Router();
        $this->setupRoutes();
    }
    
    /**
     * Loads routes from the urls.php file
     */
    function setupRoutes() {
        $router =& $this->router;
        
        $urls = require 'config/urls.php';
        $path = dirname($_SERVER['PHP_SELF']);
        $path = rtrim($path, '/');
        $router->setBasePath($path);
        
        foreach($urls as $index => $url) {
            $length = count($url);
            
            $path = '';
            $target = '';
            $options = array();
            
            switch($length) {
                case 2:
                    list($path, $target) = $url;
                    break;
                case 3:
                    list($path, $target, $options) = $url;
                    break;
                default:
                    throw new Exception('Unexpected number of entries in url, index ' . $index);
            }
            
            $router->map($path, $target, $options);
        }
        
    }
    
    /**
     * Includes the controller class file into the runtime
     */
    private function requireControllerFile($controller) {
        require sprintf('controllers/%s.php', $controller);
    }
    
    /**
     * Runs the action on thema controller object
     */
    function execute() {
        $route = $this->getRoute();
        if($route == null) {
            $path = $_SERVER['REQUEST_URI'];
            throw new Exception('No route match found for ' . $path);
            die;
        }
        
        $target = $this->getTarget($route);
        $controller = $target['controller'];
        $action = $target['action'];
        
        $this->requireControllerFile($controller);
        
        if(!is_subclass_of($controller, 'BaseController')) {
            throw new Exception(sprintf('Class %s is not a subclass of %s', $controller, 'BaseController'));
        }
        
        $controllerObj = new $controller($action, $route->getParameters());
        $controllerObj->run();
    }
    
    /**
     * Inspects the given route object and returns an array telling which action and controller is defined
     * 
     * @param Route $route
     * @return array Contains keys 'controller' and 'action'
     */
    function getTarget($route) {
        $target = $route->getTarget();
        
        list($controller, $action) = explode('#', $target);
        
        return array(
            'controller' => $controller,
            'action' => $action
        );
    }
    
    /**
     * Gets the route for the current request
     * @return Route
     */
    function getRoute() {
        return $this->router->matchCurrentRequest();
    }
    
    
}
